#!/bin/sh

e2e_test_install() {
  RESTORED_CLUSTER_NAME="$(get_sgcluster_name restored-from-s3)"
  local AWS_ACCOUNT
  AWS_ACCOUNT="$(aws sts get-caller-identity | jq -r '.Account')"
  e2e_test_uninstall || true
  aws s3 mb "s3://stackgres-e2e/"

  cat << EOF > "$LOG_PATH/policy.json"
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject"
      ],
      "Resource": [
        "arn:aws:s3:::stackgres-e2e/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket",
        "s3:GetBucketLocation"
      ],
      "Resource": [
        "arn:aws:s3:::stackgres-e2e"
      ]
    }
  ]
}
EOF

  aws iam create-policy --region "$K8S_EKS_REGION" --policy-name "stackgres-e2e-$CLUSTER_NAME" \
    --policy-document "file://$LOG_PATH/policy.json"
  aws iam create-user --region "$K8S_EKS_REGION" --user-name "stackgres-e2e-$CLUSTER_NAME"
  aws iam attach-user-policy --region "$K8S_EKS_REGION" --user-name "stackgres-e2e-$CLUSTER_NAME" \
    --policy-arn "arn:aws:iam::$AWS_ACCOUNT:policy/stackgres-e2e-$CLUSTER_NAME"
  aws iam create-access-key --region "$K8S_EKS_REGION" --user-name "stackgres-e2e-$CLUSTER_NAME" \
    > "$LOG_PATH/credentials.json"

  kubectl create namespace "$CLUSTER_NAMESPACE"
    
  kubectl create secret generic s3-credentials \
    --from-literal="accessKeyId=$(jq -r '.AccessKey.AccessKeyId' "$LOG_PATH/credentials.json")" \
    --from-literal="secretAccessKey=$(jq -r '.AccessKey.SecretAccessKey' "$LOG_PATH/credentials.json")" \
    -n "$CLUSTER_NAMESPACE"

  create_or_replace_cluster "$CLUSTER_NAME" "$CLUSTER_NAMESPACE" 1 \
    --set-string cluster.configurations.shBackupConfig=backupconf

  wait_pods_running "$CLUSTER_NAMESPACE" 1
  wait_cluster "$CLUSTER_NAME" "$CLUSTER_NAMESPACE"

  create_mock_data

  BACKUP_NAME="$(get_sgbackup_name "${CLUSTER_NAME}-0-$(shuf -i 0-65535 -n 1)")"
}

e2e_test_uninstall() {
  helm_cleanup_chart "$CLUSTER_NAME" "$CLUSTER_NAMESPACE"

  k8s_async_cleanup_namespace "$CLUSTER_NAMESPACE"

  local AWS_ACCOUNT
  AWS_ACCOUNT="$(aws sts get-caller-identity | jq -r '.Account')"
  aws iam list-access-keys --region "$K8S_EKS_REGION" --user-name "stackgres-e2e-$CLUSTER_NAME" \
    | jq -r '.AccessKeyMetadata[].AccessKeyId' \
    | xargs -r -I % aws iam delete-access-key --region "$K8S_EKS_REGION" \
      --user-name "stackgres-e2e-$CLUSTER_NAME" --access-key-id %
  aws iam detach-user-policy --region "$K8S_EKS_REGION" --user-name "stackgres-e2e-$CLUSTER_NAME" \
    --policy-arn "arn:aws:iam::$AWS_ACCOUNT:policy/stackgres-e2e-$CLUSTER_NAME"
  aws iam delete-user --region "$K8S_EKS_REGION" --user-name "stackgres-e2e-$CLUSTER_NAME"
  aws iam delete-policy --region "$K8S_EKS_REGION" \
    --policy-arn "arn:aws:iam::$AWS_ACCOUNT:policy/stackgres-e2e-$CLUSTER_NAME"
  aws s3 rm --recursive "s3://stackgres-e2e/$CLUSTER_NAMESPACE/$CLUSTER_NAME"
}

e2e_test() {
  run_test "Check that backup is executed successfully" execute_backup

  run_test "Check that restoration is executed successfully" restore_from_backup

  run_test "Check restored data integrity" check_restored_data
}

create_mock_data() {
  run_query -p 5432 -h "$CLUSTER_NAME" -n "$CLUSTER_NAMESPACE" -c "$CLUSTER_NAME" -q "CREATE DATABASE test;"
  run_query -p 5432 -h "$CLUSTER_NAME" -n "$CLUSTER_NAMESPACE" -c "$CLUSTER_NAME" -q "CREATE TABLE fibonacci(num integer);" -d "test"
  run_query -p 5432 -h "$CLUSTER_NAME" -n "$CLUSTER_NAMESPACE" -c "$CLUSTER_NAME" -q "INSERT INTO fibonacci(num) VALUES (1);" -d "test"
  run_query -p 5432 -h "$CLUSTER_NAME" -n "$CLUSTER_NAMESPACE" -c "$CLUSTER_NAME" -q "INSERT INTO fibonacci(num) VALUES (2);" -d "test"
  run_query -p 5432 -h "$CLUSTER_NAME" -n "$CLUSTER_NAMESPACE" -c "$CLUSTER_NAME" -q "INSERT INTO fibonacci(num) VALUES (3);" -d "test"
}

is_backup_phase() {
  [ "$(kubectl get sgbackup -n "$CLUSTER_NAMESPACE" "$BACKUP_NAME" -o=jsonpath='{.status.process.status}')" = "$1" ]
}

execute_backup() {
  cat << EOF | kubectl create -f -
apiVersion: stackgres.io/v1
kind: SGBackup
metadata:
  namespace: "$CLUSTER_NAMESPACE"
  name: "$BACKUP_NAME"
spec:
  sgCluster: "$CLUSTER_NAME"
  managedLifecycle: false
EOF
  
  wait_until is_backup_phase "Completed"

  success "Backup completed"
}

restore_from_backup() {
  kubectl delete sgclusters.stackgres.io -n "$CLUSTER_NAMESPACE" "$CLUSTER_NAME"

  BACKUP_UID="$(kubectl get sgbackups.stackgres.io -n "$CLUSTER_NAMESPACE" "$BACKUP_NAME" -o=jsonpath='{.metadata.uid}')"

  cat <<EOF | kubectl apply -f -
apiVersion: stackgres.io/v1
kind: SGCluster
metadata:
  name: $RESTORED_CLUSTER_NAME
  namespace: $CLUSTER_NAMESPACE
spec:
  instances: 2
  postgres:
    version: 'latest'
  sgInstanceProfile: size-s
  pods:
    persistentVolume:
      size: '512Mi'
  initialData:
    restore:
      downloadDiskConcurrency: 10
      fromBackup:
        uid: "$BACKUP_UID"
EOF

  wait_pods_running "$CLUSTER_NAMESPACE" 2

  success "Cluster restored from backup $BACKUP_NAME"
}

check_restored_data() {
  REPLICA_RESPONSE="$(run_query -p 5432 -h "$RESTORED_CLUSTER_NAME-replicas" -c "$RESTORED_CLUSTER_NAME" -n "$CLUSTER_NAMESPACE" -i 1 -q "SELECT num FROM fibonacci ORDER BY num;" -d "test")"
  if [ "$(echo "$REPLICA_RESPONSE" | tr -d '\n')" = "123" ]
  then
    success "restore replica db restored successfully"
  else
    fail "replica db not restored"
  fi
}
